home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / comm1 / intsdkss.lha / examples / udp / udp_client.c < prev    next >
C/C++ Source or Header  |  1996-04-09  |  4KB  |  166 lines

  1. /*
  2. ** UDP client program
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. #include <netdb.h>
  10. #include <sys/types.h>
  11. #include <sys/time.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <proto/socket.h>
  15.  
  16. #define DEFAULT_PORT 54321
  17. #define MAX_RETRIES 10
  18. #define TIMEOUT_SECS 1
  19. #define TERMINATOR "quit\n"
  20.  
  21. main ( argc, argv )
  22.      int argc;
  23.      char *argv[];
  24. {
  25. int s, retcode, done, retry, match, timeout;
  26. long fromlen;
  27. char recvbuffer[256], sendbuffer[256];
  28. struct sockaddr_in addr, from;
  29. struct servent * sp;
  30. struct hostent * hp;
  31. struct timeval timer;
  32. fd_set rfds;
  33.  
  34. if ( argc != 2 ) {
  35.     fprintf ( stderr, "Usage:\t %s host \n", argv[0]);
  36.     exit (1);
  37. }
  38.  
  39. /*
  40. ** Users may specify hosts in 2 different formats:
  41. ** hostnames or IP addresses (aka dotted quads).
  42. ** First try looking up the host as a hostname, and
  43. ** if that fails try as an IP address.
  44. */
  45.  
  46. memset(&addr, 0, sizeof(struct sockaddr_in) );
  47. hp = gethostbyname( argv[1] );
  48. if ( hp != NULL ) {
  49.     addr.sin_family = hp->h_addrtype ;
  50.     addr.sin_addr.s_addr = *((int *) hp ->h_addr);
  51. } else {
  52.     addr.sin_family = AF_INET;
  53.     addr.sin_addr.s_addr = inet_addr( argv[1] );
  54.     if (addr.sin_addr.s_addr == -1) {
  55.     fprintf(stderr,"Can't lookup host %s\n",argv[1]);
  56.     exit(1);
  57.     }
  58. }
  59.  
  60. /*
  61. ** Applications should get the service number from the services file.
  62. ** Try the services file first, and upon failure, use a default port
  63. ** number.  This allows the example to run without modifying the
  64. ** system environment.
  65. */
  66. sp = getservbyname( "example", "udp" );
  67. if( sp != NULL ) {
  68.     addr.sin_port = sp->s_port;
  69. } else {
  70.     addr.sin_port = DEFAULT_PORT;
  71. }
  72.  
  73. /*
  74. ** Create a socket.
  75. */
  76. s = socket ( AF_INET, SOCK_DGRAM, 0 );
  77. if ( s == -1 ) {
  78.     perror("socket");
  79.     exit(1);
  80. }
  81.  
  82. /*
  83. ** Client main loop - read data from stdin, send to server.
  84. ** Server echos back data, client reads data and prints on stdout.
  85. ** User may type quit or EOF to terminate program.
  86. ** Since data may get lost, the program must be prepared to
  87. ** deal with a lost message.  This simple client uses select
  88. ** to wait for the incoming packet or a timeout.  After a
  89. ** timeout it will retransmit the packet up to MAX_RETRIES
  90. ** times before giving up.  If the program receives a packet
  91. ** that doesn't contain the expected data it is dropped.
  92. */
  93.  
  94. printf("Type a message, then type EOF character or quit to quit\n");
  95. done = 0;
  96. while (!done) {                                         /* Main Client Loop */
  97.  
  98.     if( fgets(sendbuffer, sizeof(sendbuffer), stdin) == NULL ){
  99.     if (feof(stdin)) {
  100.         strcpy(sendbuffer, "quit\n");
  101.         fprintf(stderr,"EOF - terminating server\n");
  102.     }
  103.     else {
  104.         perror("fgets");
  105.         exit(1);
  106.     }
  107.     }
  108.     if (!strncmp(sendbuffer, TERMINATOR, strlen(TERMINATOR))) {
  109.     done = 1;
  110.     }
  111.  
  112.     retry = MAX_RETRIES+1;
  113.     match = 0;
  114.     while(!match && retry) {                            /* Transmit Loop */
  115.     retcode = sendto(s, sendbuffer, strlen(sendbuffer),
  116.                 0, (struct sockaddr *)&addr, sizeof(addr));
  117.     if(retcode < 0 ) {
  118.         perror("sendto");
  119.         exit(1);
  120.     }
  121.  
  122.     timeout = 0;
  123.     while(!match && !timeout) {                     /* Timeout Loop */
  124.         FD_ZERO(&rfds);
  125.         FD_SET(s, &rfds);
  126.         timer.tv_sec = TIMEOUT_SECS;
  127.         timer.tv_usec = 0;
  128.         retcode = select(s+1, &rfds, NULL, NULL, &timer);
  129.         if (retcode < 0) {
  130.         perror("select");
  131.         exit(1);
  132.         }
  133.         else if ( retcode == 0 ) {                  /* Timeout */
  134.         if (--retry) {
  135.             fprintf(stderr,"Client Timeout, retransmitting data\n");
  136.             timeout = 1;
  137.         }
  138.         else {
  139.             fprintf(stderr,"Client Timeout - giving up\n");
  140.             exit(1);
  141.         }
  142.         }
  143.         else {                    /* Get Packet */
  144.         fromlen = sizeof(from);
  145.         retcode = recvfrom(s, recvbuffer, sizeof(recvbuffer),
  146.                     0, (struct sockaddr*)&from, &fromlen);
  147.         if ( retcode < 0 ){
  148.             perror("recvfrom");
  149.             exit(1);
  150.         }
  151.         recvbuffer[retcode] = 0;
  152.         fprintf(stdout,
  153.            "Response from %s, port %d, length %3d, data %s",
  154.            inet_ntoa(from.sin_addr),from.sin_port, retcode, recvbuffer);
  155.  
  156.         if (!strcmp( sendbuffer, recvbuffer )) {/* Check Packet */
  157.             fputs(recvbuffer, stdout);
  158.             match=1;
  159.         }
  160.         }
  161.     }
  162.     }
  163. }
  164. exit(0);
  165. }
  166.